<!DOCTYPE html>
<html lang="zh_cn">
<head>
          <title>来玩魔王的咚</title>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta charset="utf-8" />
        <!-- twitter card metadata -->
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="/images/mowang.png">
<meta name="twitter:site" content="">
<meta name="twitter:title" content="Zabbix Graphtrees 插件">
<meta name="twitter:description" content="<p>Zabbix的graphtree插件的安装和使用效果；解决生成环境大量图片请求有图片加载失败的问题；解决zabbix4.4版本上插件兼容性的问题；用户未登录可以隐藏菜单</p>">
        <!-- OG Tags -->
<meta property="og:url" content="/zabbix-plugin-graphtrees.html"/>
<meta property="og:title" content="来玩魔王的咚 | Zabbix Graphtrees 插件" />
<meta property="og:description" content="<p>Zabbix的graphtree插件的安装和使用效果；解决生成环境大量图片请求有图片加载失败的问题；解决zabbix4.4版本上插件兼容性的问题；用户未登录可以隐藏菜单</p>" />
        <!-- favicon -->
        <link rel="icon" type="image/png" href="/images/mowang.png">
        <!-- moment.js for date formatting -->
        <script src="/theme/js/moment.js"></script>
        <!-- css -->
        <link rel="stylesheet" type="text/css" href="/theme/css/main.css" />
        <!-- 左边的menu，如果页面高度不够，就跟着滚动，否则文章分类显示不全 -->
        <link rel="stylesheet" type="text/css" href="/theme/css/mycss/menu.css" />
		<script>
			
                /*! grunt-grunticon Stylesheet Loader - v2.1.2 | https://github.com/filamentgroup/grunticon | (c) 2015 Scott Jehl, Filament Group, Inc. | MIT license. */
    
    (function(e){function t(t,n,r,o){"use strict";function a(){for(var e,n=0;u.length>n;n++)u[n].href&&u[n].href.indexOf(t)>-1&&(e=!0);e?i.media=r||"all":setTimeout(a)}var i=e.document.createElement("link"),l=n||e.document.getElementsByTagName("script")[0],u=e.document.styleSheets;return i.rel="stylesheet",i.href=t,i.media="only x",i.onload=o||null,l.parentNode.insertBefore(i,l),a(),i}var n=function(r,o){"use strict";if(r&&3===r.length){var a=e.navigator,i=e.Image,l=!(!document.createElementNS||!document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect||!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1")||e.opera&&-1===a.userAgent.indexOf("Chrome")||-1!==a.userAgent.indexOf("Series40")),u=new i;u.onerror=function(){n.method="png",n.href=r[2],t(r[2])},u.onload=function(){var e=1===u.width&&1===u.height,a=r[e&&l?0:e?1:2];n.method=e&&l?"svg":e?"datapng":"png",n.href=a,t(a,null,null,o)},u.src="",document.documentElement.className+=" grunticon"}};n.loadCSS=t,e.grunticon=n})(this);(function(e,t){"use strict";var n=t.document,r="grunticon:",o=function(e){if(n.attachEvent?"complete"===n.readyState:"loading"!==n.readyState)e();else{var t=!1;n.addEventListener("readystatechange",function(){t||(t=!0,e())},!1)}},a=function(e){return t.document.querySelector('link[href$="'+e+'"]')},c=function(e){var t,n,o,a,c,i,u={};if(t=e.sheet,!t)return u;n=t.cssRules?t.cssRules:t.rules;for(var l=0;n.length>l;l++)o=n[l].cssText,a=r+n[l].selectorText,c=o.split(");")[0].match(/US\-ASCII\,([^"']+)/),c&&c[1]&&(i=decodeURIComponent(c[1]),u[a]=i);return u},i=function(e){var t,o,a;o="data-grunticon-embed";for(var c in e)if(a=c.slice(r.length),t=n.querySelectorAll(a+"["+o+"]"),t.length)for(var i=0;t.length>i;i++)t[i].innerHTML=e[c],t[i].style.backgroundImage="none",t[i].removeAttribute(o);return t},u=function(t){"svg"===e.method&&o(function(){i(c(a(e.href))),"function"==typeof t&&t()})};e.embedIcons=i,e.getCSS=a,e.getIcons=c,e.ready=o,e.svgLoadedCallback=u,e.embedSVG=u})(grunticon,this);
                
                grunticon(["/theme/css/icons.data.svg.css", "/theme/css/icons.data.png.css", "/theme/css/icons.fallback.css"]);
            </script>
        <noscript><link href="/theme/css/icons.fallback.css" rel="stylesheet"></noscript>
        <!-- menu toggle javascript -->
        <script type="text/javascript">
            document.addEventListener("DOMContentLoaded", initMenu);
            
            function initMenu(){
                var menu = document.getElementById("menu");
                var menulink = document.getElementById("menu-link");
                menulink.addEventListener("click", function toggleMenu(){
                        window.event.preventDefault();
                        menulink.classList.toggle('active');
                        menu.classList.toggle('active');              
                    });
            };
        </script>
        <!-- 不蒜子 -->
        <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>

    <meta name="description" content="<p>Zabbix的graphtree插件的安装和使用效果；解决生成环境大量图片请求有图片加载失败的问题；解决zabbix4.4版本上插件兼容性的问题；用户未登录可以隐藏菜单</p>" />

    <meta name="tags" content="zabbix" />
    <meta name="tags" content="graphtrees" />
  <!-- 替换部分base的样式，看文章时，要再宽一点，右边有很多空间可以撑开 -->
  <link rel="stylesheet" type="text/css" href="/theme/css/mycss/article.css" />

</head>
<body>
    <div role="banner" id="masthead">
        <header>
            <a href="/"><img src="/images/mowang.png" alt="McManus Logo"></a>
                <h1>来玩魔王的咚@骑士救兵</h1>
            <a href="#menu" id="menu-link">more stuff</a>
            <nav id="menu">
                <ul>
                        <li><a href="/tags">tags</a></li>
                            <li><a href="/category/cloud.html">Cloud</a></li>
                            <li><a href="/category/docker.html">Docker</a></li>
                            <li><a href="/category/go.html">Go</a></li>
                            <li><a href="/category/linux.html">Linux</a></li>
                            <li><a href="/category/python.html">Python</a></li>
                            <li><a href="/category/xue-xi-bi-ji.html">学习笔记</a></li>
                            <li class="active"><a href="/category/yun-wei-zi-dong-hua.html">运维自动化</a></li>
                </ul>
            </nav>
        </header>
    </div>
        <div class="page" role="main">
  <div class="article" role="article">
    <article>
        <footer>
            <a name="top"></a>
            <p>
              <time datetime=" 2020-07-10 15:30:00+08:00">
                <script>document.write(moment('2020-07-10 15:30:00+08:00').format('LL'));</script>
              </time>
              ~
              <time datetime=" 2020-07-10 15:30:00+08:00">
                <script>document.write(moment('2020-07-10 15:30:00+08:00').format('LL'));</script>
              </time>
            </p>
        </footer>
        <header>
          <h2>
            Zabbix Graphtrees 插件
          </h2>
        </header>
      <div class="content">
         <div class="toc">
<ul>
<li><a href="#an-zhuang-bu-zhou">安装步骤</a><ul>
<li><a href="#xie-zai-cha-jian">卸载插件</a></li>
</ul>
</li>
<li><a href="#xiao-guo-zhan-shi">效果展示</a></li>
<li><a href="#ye-mian-xiu-gai">页面修改</a></li>
<li><a href="#bu-fen-tu-pian-jia-zai-shi-bai">部分图片加载失败</a><ul>
<li><a href="#ke-hu-duan-shou-dong-jie-jue">客户端手动解决</a></li>
<li><a href="#xiu-gai-qian-duan-dai-ma-jie-jue">修改前端代码解决</a></li>
</ul>
</li>
<li><a href="#wu-fa-xiu-gai-shi-jian">无法修改时间</a><ul>
<li><a href="#yuan-yin-fen-xi">原因分析</a></li>
</ul>
</li>
<li><a href="#xiu-gai-de-dai-ma-bu-fen">修改的代码部分</a></li>
<li><a href="#dui-wei-deng-lu-yong-hu-yin-cang-graphtree-cai-dan">对未登录用户隐藏Graphtree菜单</a><ul>
<li><a href="#ye-mian-bei-huan-cun-de-wen-ti">页面被缓存的问题</a></li>
<li><a href="#yin-cang-cai-dan-xiang">隐藏菜单项</a></li>
<li><a href="#dan-chu-deng-lu-ti-xing">弹出登录提醒</a></li>
</ul>
</li>
</ul>
</div>
<p>Zabbix-Network-Weathermap 和 Graphtree for Zabbix 是 <a href="https://share.zabbix.com/zabbix-tools-and-utilities/web-addons">Zabbix Share</a>上标了 Popular 的 3.0.x 版本的插件。这篇讲Graphtree。<br>
Graphtree项目地址：https://github.com/OneOaaS/graphtrees<br>
我是直接在zabbix4.4上装的，所以新的版本也是可以用的。但是会有一些问题，后面有解决办法。<br>
<strong>主要功能：</strong>简单说就是可以集中展示一类或一组图片。装完就能用，不用设置挺方便的。  </p>
<h3 id="an-zhuang-bu-zhou"><a class="toclink" href="#an-zhuang-bu-zhou">安装步骤</a></h3>
<p>安装在 zabbix-web 所在的服务器：</p>
<div class="highlight"><pre><span></span><code><span class="c1"># 安装工具包  </span>
$ yum install patch  
<span class="c1"># 切换到准备部署的目录  </span>
$ <span class="nb">cd</span> /usr/share/zabbix  
<span class="c1"># 下载插件  </span>
$ wget https://raw.githubusercontent.com/OneOaaS/graphtrees/master/graphtree3.2.x.patch  
<span class="c1"># 在当前路径解压，部署  </span>
$ patch  -Np0 &lt; graphtree3.2.x.patch  
<span class="c1"># 将文件夹权限的属主和属组改为web应用的账号  </span>
$ chown -R apache:apache oneoaas 
</code></pre></div>

<p>然后还要去修改一下apache的配置文件（实际貌似不需要）：</p>
<div class="highlight"><pre><span></span><code><span class="c1">#vi /etc/httpd/conf.d/zabbix.conf       </span>
Alias /oneoaas /usr/share/zabbix/oneoaas        
Alias /zabbix /user/share/zabbix    
</code></pre></div>

<p>加上上面第一行的配置，第二行是原本就有的配置。<br>
这个实际用下来发现不用改。项目访问的url是 127.0.0.1/zabbix/oneoaas 。这个地址可以直接通过<code>Alias /zabbix</code>就访问到了。<br>
而<code>Alias /oneoaas</code>这条配置加上之后，是可以通过 127.0.0.1/oneoaas 来访问项目。实际不是通过这个url来访问的。所以这个apache的配置不用加。  </p>
<p><strong>不用重启</strong><br>
无论是项目的部署，还是apache配置的修改，都不用重启任何服务，直接就生效了。  </p>
<h4 id="xie-zai-cha-jian"><a class="toclink" href="#xie-zai-cha-jian">卸载插件</a></h4>
<p>使用patch的好处是，如果需要卸载，可以使用 -R --reverse 选项，就把之前创建的文件给清理掉，并且把修改的文件恢复回来（修改文件会创建一个备份，此时就是把新文件给清理掉，把备份文件的名字改回来）：</p>
<div class="highlight"><pre><span></span><code>$ patch  -Rp0 &lt; graphtree3.2.x.patch
</code></pre></div>

<h3 id="xiao-guo-zhan-shi"><a class="toclink" href="#xiao-guo-zhan-shi">效果展示</a></h3>
<p>安装完成后，无需重启，马上就生效了。登录zabbix主页查看，菜单上多了一个Graphtree：<br>
<img alt="Graphtree菜单" src="/images/zabbix/02_graphtree-menu.jpg"></p>
<p>进入项目后，可以自动获取到主机和主机组的信息，在左上角：<br>
<img alt="Graphtree主页" src="/images/zabbix/02_graphtree-index.jpg"></p>
<p>点击主机组，可以查看所有主机组的的图像。<br>
点击主机，可以查看主机上所有图像。<br>
勾选要展示的主机，搜索框输入要搜索的关键字，可以筛选展示需要的图像：<br>
<img alt="Graphtree搜索" src="/images/zabbix/02_graphtree-search.jpg"></p>
<h3 id="ye-mian-xiu-gai"><a class="toclink" href="#ye-mian-xiu-gai">页面修改</a></h3>
<p>左上角的项目图标，点击会连到项目公司的主页，而不是Zabbix首页，经常点错很不方便。可以把连接改掉，要改图标也是可以的。<br>
另外页脚的内容如果看着不喜欢也能删掉，不过这个在下面不太影响使用。<br>
就是修个这个文件 <code>oneoaas/templates/graphtree/graphtree.tpl</code> ，懂点 html 就明白了，具体就略过了。  </p>
<h3 id="bu-fen-tu-pian-jia-zai-shi-bai"><a class="toclink" href="#bu-fen-tu-pian-jia-zai-shi-bai">部分图片加载失败</a></h3>
<p>这个是生产环境上出现的问题。一个页面上一次加载的大量图片中，总有一些显示的叉叉，这个是前端加载图片失败的结果。  </p>
<h4 id="ke-hu-duan-shou-dong-jie-jue"><a class="toclink" href="#ke-hu-duan-shou-dong-jie-jue">客户端手动解决</a></h4>
<p>在加载失败的图片上，鼠标右键 -&gt; 显示图片。就是手动发起再次请求资源，图片就能显示出来。<br>
不是所有的浏览器都有这个功能的，而且每次都要一张张把加载失败的图片手动请求一遍也很麻烦。所以这并不是最终解决的办法，但是至少找到了一个前端解决的途径。之后就是通过代码来让这个操作自动执行。  </p>
<h4 id="xiu-gai-qian-duan-dai-ma-jie-jue"><a class="toclink" href="#xiu-gai-qian-duan-dai-ma-jie-jue">修改前端代码解决</a></h4>
<p>为img标签加上onerror事件，然后在通过onerror的函数来重新加载图片。  </p>
<h5 id="xiu-gai-biao-qian"><a class="toclink" href="#xiu-gai-biao-qian">修改标签</a></h5>
<p>在原来的标签的基础上，加一个onerror事件，再加一个又来记录重试次数的变量retry：</p>
<div class="highlight"><pre><span></span><code><span class="c1">//&#39;&lt;img src=&quot;../&#39;+ handle +&#39;?graphid=&#39;+ ctx.graphid +&#39;&amp;width=520&amp;height=260&amp;stime=&#39;+timeline.stime+&#39;&amp;period=&#39;+timeline.period+&#39;&quot;&gt;&#39;</span><span class="w"></span>
<span class="s1">&#39;&lt;img src=&quot;../&#39;</span><span class="o">+</span><span class="w"> </span><span class="nx">handle</span><span class="w"> </span><span class="o">+</span><span class="s1">&#39;?graphid=&#39;</span><span class="o">+</span><span class="w"> </span><span class="nx">ctx</span><span class="p">.</span><span class="nx">graphid</span><span class="w"> </span><span class="o">+</span><span class="s1">&#39;&amp;width=520&amp;height=260&amp;stime=&#39;</span><span class="o">+</span><span class="nx">timeline</span><span class="p">.</span><span class="nx">stime</span><span class="o">+</span><span class="s1">&#39;&amp;period=&#39;</span><span class="o">+</span><span class="nx">timeline</span><span class="p">.</span><span class="nx">period</span><span class="o">+</span><span class="s1">&#39;&quot; retry=0 onerror=&quot;graph.imgretry(this);&quot;&gt;&#39;</span><span class="w"></span>
</code></pre></div>

<h5 id="zhong-shi-han-shu"><a class="toclink" href="#zhong-shi-han-shu">重试函数</a></h5>
<p>编写进行重试的函数 graph.imgretr 。<br>
加上重试次数的限制，如果多次重试后仍然失败，则不会无限的重试下去。<br>
重试之前加上一个等待时间，并且时间随机。这样不会所有失败的图片再在同一时间向服务器同时发起请求。  </p>
<h3 id="wu-fa-xiu-gai-shi-jian"><a class="toclink" href="#wu-fa-xiu-gai-shi-jian">无法修改时间</a></h3>
<p>生成的图片只能是最近一小时（最近1小时是默认的时间区间选择范围），要选定时间无效。  </p>
<h4 id="yuan-yin-fen-xi"><a class="toclink" href="#yuan-yin-fen-xi">原因分析</a></h4>
<p>这个插件是为3.x的zabbix做的，果然在4.x版本就不能用了。不过也能解决。<br>
具体原因是请求的url参数使用的是stime(开始时间的时间抽)和period(持续的秒数)。<br>
新版本变成了from(起始时间的字符串)和to(结束时间的字符串)，另外还要加上<code>profileIdx=web.graphs.filter</code><br>
代码片段:</p>
<div class="highlight"><pre><span></span><code><span class="nx">tmp_a</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="w"></span>
<span class="w">        </span><span class="c1">//&#39;&lt;img src=&quot;../&#39;+ handle +&#39;?graphid=&#39;+ ctx.graphid +&#39;&amp;width=520&amp;height=260&amp;stime=&#39;+timeline.stime+&#39;&amp;period=&#39;+timeline.period+&#39;&quot;&gt;&#39;</span><span class="w"></span>
<span class="w">        </span><span class="s1">&#39;&lt;img src=&quot;../&#39;</span><span class="o">+</span><span class="w"> </span><span class="nx">handle</span><span class="w"> </span><span class="o">+</span><span class="s1">&#39;?graphid=&#39;</span><span class="o">+</span><span class="w"> </span><span class="nx">ctx</span><span class="p">.</span><span class="nx">graphid</span><span class="w"> </span><span class="o">+</span><span class="w"></span>
<span class="w">        </span><span class="s1">&#39;&amp;width=520&amp;height=260&amp;from=&#39;</span><span class="o">+</span><span class="w"> </span><span class="nb">encodeURIComponent</span><span class="p">(</span><span class="nx">starttime</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="s1">&#39;&amp;to=&#39;</span><span class="o">+</span><span class="w"> </span><span class="nb">encodeURIComponent</span><span class="p">(</span><span class="nx">endtime</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"></span>
<span class="w">        </span><span class="s1">&#39;&amp;profileIdx=web.graphs.filter&quot; retry=0 onerror=&quot;graph.imgretry(this);&quot;&gt;&#39;</span><span class="w"></span>
<span class="p">);</span><span class="w"></span>
</code></pre></div>

<p><em>这里主要展示参数的差别，完整的代码修改见下一节。</em></p>
<h3 id="xiu-gai-de-dai-ma-bu-fen"><a class="toclink" href="#xiu-gai-de-dai-ma-bu-fen">修改的代码部分</a></h3>
<p>包括了上面2个问题完整的修改。<br>
要修改的文件是 oneoaas/templates/graphtree/graphtree.tpl ，这个文件。<br>
<em>代码又长又宽，页面上分不清折行。建议复制粘贴到本地的编辑器（记事本）上看。</em><br>
修改的部分代码：</p>
<div class="highlight"><pre><span></span><code><span class="kd">var</span><span class="w"> </span><span class="nx">graph</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="c1">// 省略graph中的其他代码</span><span class="w"></span>

<span class="w">    </span><span class="c1">// 自定义图片加载失败的重试方法</span><span class="w"></span>
<span class="w">    </span><span class="nx">imgretry</span><span class="o">:</span><span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">){</span><span class="w"></span>
<span class="w">        </span><span class="kd">var</span><span class="w"> </span><span class="nx">retry</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">$</span><span class="p">(</span><span class="nx">x</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s1">&#39;retry&#39;</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="k">if</span><span class="p">(</span><span class="nx">retry</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mf">3</span><span class="p">){</span><span class="w"></span>
<span class="w">            </span><span class="nx">retry</span><span class="o">++</span><span class="p">;</span><span class="w"></span>
<span class="w">            </span><span class="kd">var</span><span class="w"> </span><span class="nx">rand</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">parseInt</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">1000</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">300</span><span class="p">)</span><span class="w">  </span><span class="c1">// 随机等待[300,1300)ms</span><span class="w"></span>
<span class="w">            </span><span class="c1">//console.log(rand)</span><span class="w"></span>
<span class="w">            </span><span class="nx">$</span><span class="p">(</span><span class="nx">x</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s1">&#39;retry&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">retry</span><span class="p">);</span><span class="w"></span>
<span class="w">            </span><span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span><span class="w"></span>
<span class="w">                </span><span class="nx">x</span><span class="p">.</span><span class="nx">src</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">$</span><span class="p">(</span><span class="nx">x</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s1">&#39;src&#39;</span><span class="p">);</span><span class="w"></span>
<span class="w">            </span><span class="p">},</span><span class="w"> </span><span class="nx">rand</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="k">else</span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="nx">x</span><span class="p">.</span><span class="nx">onerror</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">},</span><span class="w"></span>

<span class="w">    </span><span class="nx">makeGraph</span><span class="o">:</span><span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">){</span><span class="w"></span>
<span class="w">        </span><span class="c1">// 省略graph.makeGraph中的其他代码</span><span class="w"></span>

<span class="w">        </span><span class="c1">// 追加时间戳转日期时间的处理</span><span class="w"></span>
<span class="w">        </span><span class="k">if</span><span class="p">(</span><span class="nx">timeline</span><span class="p">.</span><span class="nx">etime</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s1">&#39;&#39;</span><span class="p">){</span><span class="w"></span>
<span class="w">            </span><span class="nx">timeline</span><span class="p">.</span><span class="nx">etime</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">parseInt</span><span class="p">(</span><span class="nx">timeline</span><span class="p">.</span><span class="nx">stime</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">parseInt</span><span class="p">(</span><span class="nx">timeline</span><span class="p">.</span><span class="nx">period</span><span class="p">)</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="kd">var</span><span class="w"> </span><span class="nx">timezone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">+</span><span class="mf">8</span><span class="w"></span>
<span class="w">        </span><span class="kd">var</span><span class="w"> </span><span class="nx">starttime</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">$</span><span class="p">.</span><span class="nx">myTime</span><span class="p">.</span><span class="nx">UnixToDate</span><span class="p">(</span><span class="nx">timeline</span><span class="p">.</span><span class="nx">stime</span><span class="p">,</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="nx">timezone</span><span class="p">)</span><span class="w"></span>
<span class="w">        </span><span class="kd">var</span><span class="w"> </span><span class="nx">endtime</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">$</span><span class="p">.</span><span class="nx">myTime</span><span class="p">.</span><span class="nx">UnixToDate</span><span class="p">(</span><span class="nx">timeline</span><span class="p">.</span><span class="nx">etime</span><span class="p">,</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="nx">timezone</span><span class="p">)</span><span class="w"></span>

<span class="w">        </span><span class="nx">graph</span><span class="p">.</span><span class="nx">selector</span><span class="p">.</span><span class="nx">children</span><span class="p">().</span><span class="nx">remove</span><span class="p">();</span><span class="w"></span>
<span class="w">        </span><span class="nx">jQuery</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">content</span><span class="p">.</span><span class="nx">graphs</span><span class="p">,</span><span class="kd">function</span><span class="p">(</span><span class="nx">idx</span><span class="p">,</span><span class="nx">ctx</span><span class="p">){</span><span class="w"></span>
<span class="w">            </span><span class="c1">//var tmp_a = jQuery(&#39;&lt;a class=&quot;graph_img&quot; href=&quot;../charts.php?graphid=&#39;+ctx.graphid+&#39;&amp;stime=&#39;+timeline.stime+&#39;&amp;period=&#39;+timeline.period+&#39;&quot;&gt;&lt;/a&gt;&#39;);</span><span class="w"></span>
<span class="w">            </span><span class="kd">var</span><span class="w"> </span><span class="nx">tmp_a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">jQuery</span><span class="p">(</span><span class="s1">&#39;&lt;a class=&quot;graph_img&quot; &#39;</span><span class="w"> </span><span class="o">+</span><span class="w"></span>
<span class="w">                </span><span class="s1">&#39;href=&quot;../charts.php?graphid=&#39;</span><span class="o">+</span><span class="nx">ctx</span><span class="p">.</span><span class="nx">graphid</span><span class="o">+</span><span class="s1">&#39;&amp;from=&#39;</span><span class="o">+</span><span class="w"> </span><span class="nb">encodeURIComponent</span><span class="p">(</span><span class="nx">starttime</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="s1">&#39;&amp;to=&#39;</span><span class="o">+</span><span class="nb">encodeURIComponent</span><span class="p">(</span><span class="nx">endtime</span><span class="p">)</span><span class="o">+</span><span class="s1">&#39;&quot;&gt;&lt;/a&gt;&#39;</span><span class="p">);</span><span class="w"></span>
<span class="w">            </span><span class="kd">var</span><span class="w"> </span><span class="nx">handle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;chart2.php&#39;</span><span class="p">;</span><span class="w"></span>
<span class="w">            </span><span class="k">if</span><span class="p">(</span><span class="nx">ctx</span><span class="p">.</span><span class="nx">graphtype</span><span class="w"> </span><span class="o">==</span><span class="mf">2</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nx">ctx</span><span class="p">.</span><span class="nx">graphtype</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mf">3</span><span class="p">){</span><span class="w"></span>
<span class="w">                </span><span class="nx">handle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;chart6.php&#39;</span><span class="p">;</span><span class="w"></span>
<span class="w">            </span><span class="p">}</span><span class="w"></span>
<span class="w">            </span><span class="nx">tmp_a</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="w"></span>
<span class="w">                    </span><span class="c1">//&#39;&lt;img src=&quot;../&#39;+ handle +&#39;?graphid=&#39;+ ctx.graphid +&#39;&amp;width=520&amp;height=260&amp;stime=&#39;+timeline.stime+&#39;&amp;period=&#39;+timeline.period+&#39;&quot;&gt;&#39;</span><span class="w"></span>
<span class="w">                    </span><span class="s1">&#39;&lt;img src=&quot;../&#39;</span><span class="o">+</span><span class="w"> </span><span class="nx">handle</span><span class="w"> </span><span class="o">+</span><span class="s1">&#39;?graphid=&#39;</span><span class="o">+</span><span class="w"> </span><span class="nx">ctx</span><span class="p">.</span><span class="nx">graphid</span><span class="w"> </span><span class="o">+</span><span class="w"></span>
<span class="w">                    </span><span class="s1">&#39;&amp;width=520&amp;height=260&amp;from=&#39;</span><span class="o">+</span><span class="w"> </span><span class="nb">encodeURIComponent</span><span class="p">(</span><span class="nx">starttime</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="s1">&#39;&amp;to=&#39;</span><span class="o">+</span><span class="w"> </span><span class="nb">encodeURIComponent</span><span class="p">(</span><span class="nx">endtime</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"></span>
<span class="w">                    </span><span class="s1">&#39;&amp;profileIdx=web.graphs.filter&quot; retry=0 onerror=&quot;graph.imgretry(this);&quot;&gt;&#39;</span><span class="w"></span>
<span class="w">            </span><span class="p">);</span><span class="w"></span>
<span class="w">            </span><span class="nx">graph</span><span class="p">.</span><span class="nx">selector</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="nx">tmp_a</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="p">});</span><span class="w"></span>

<span class="w">        </span><span class="c1">// 省略graph.makeGraph中的其他代码</span><span class="w"></span>
<span class="w">    </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="c1">// 省略graph中的其他代码</span><span class="w"></span>
<span class="p">};</span><span class="w"></span>
</code></pre></div>

<p>重新加载图片之前，等待的时间还算是比较长的，能明显感觉再图片有过加载失败，然后重启后再刷出来的。正好可以验证下效果。之后可以在适当的对等待的时间进行调整。  </p>
<h3 id="dui-wei-deng-lu-yong-hu-yin-cang-graphtree-cai-dan"><a class="toclink" href="#dui-wei-deng-lu-yong-hu-yin-cang-graphtree-cai-dan">对未登录用户隐藏Graphtree菜单</a></h3>
<p>未登录的账号也是可以浏览仪表盘的，并且也能看到Graphtree的菜单项。<br>
但是点击后是进不去的，并且应该会弹到错误页面，或者是apache默认的首页。<br>
更讨厌的是，跳转到的这个错误页面一般都是静态页面，会被缓存。之后用户即使登录了也还是无法进入正确的页面。  </p>
<h4 id="ye-mian-bei-huan-cun-de-wen-ti"><a class="toclink" href="#ye-mian-bei-huan-cun-de-wen-ti">页面被缓存的问题</a></h4>
<p>页面被缓存了，即使你之后登陆了，再尝试进入，也是继续给你之前缓存的页面。两个办法解决：<br>
<strong>方法一：</strong>关闭浏览器，再打开，这类缓存的内容就没了。<br>
<strong>方法二：</strong>使用浏览器的清除历史记录，只需要清除“Cookie和保存的网站数据”就可以了。<br>
推荐还是方法一吧，简单点。  </p>
<h4 id="yin-cang-cai-dan-xiang"><a class="toclink" href="#yin-cang-cai-dan-xiang">隐藏菜单项</a></h4>
<p>防止未登录而误点的办法就是把菜单项隐藏掉。具体如下:  </p>
<div class="highlight"><pre><span></span><code>$ grep -C2 Graphtree zabbix/include/menu.inc.php      
                                <span class="o">[</span>
                                        <span class="s1">&#39;url&#39;</span> <span class="o">=</span>&gt; <span class="s1">&#39;oneoaas/graphtree.php&#39;</span>,
                                        <span class="s1">&#39;label&#39;</span> <span class="o">=</span>&gt; _<span class="o">(</span><span class="s1">&#39;Graphtree&#39;</span><span class="o">)</span>,
                                        <span class="s1">&#39;user_type&#39;</span> <span class="o">=</span>&gt; USER_TYPE_ZABBIX_USER
                                <span class="o">]</span>,
</code></pre></div>

<p>最后一行的user_type是新增的代码，注意上一行的结尾加上逗号。  </p>
<h4 id="dan-chu-deng-lu-ti-xing"><a class="toclink" href="#dan-chu-deng-lu-ti-xing">弹出登录提醒</a></h4>
<p>这个问题我暂时没能力解决。原生的页面如果权限不够，会看着这个页面，并且还有个按钮跳转到登录页面。  </p>
<p>虽然隐藏了菜单，但是还是不能防止其他办法尝试进入页面。比如直接通过url访问。<br>
如果尝试进入没有权限的Zabbix原生页面，zabbix会返回一个警告，并且可以点击login跳转到登录页面。<br>
这是通过调用<code>zabbix/include/func.inc.php</code>里的access_deny函数实现的。<br>
函数找到了，但是用不来。接下来的步骤应该是在graphtree项目的php文件里调用这个函数。这步我卡住做不下去了。  </p>
      </div>
      <div class="back-to-top">
        <a href="/">HOME</a>
        <a href="#top">TOP</a>
      </div>
    </article>
  </div>
<!-- end article -->
<!-- 页面往下滚动一段之后才会显示TOC -->
<script>
  window.onscroll = function() {
    var tocbox = document.getElementsByClassName('toc')[0];
    var osTop = document.documentElement.scrollTop || document.body.scrollTop;
    var osWidth = document.documentElement.scrollWidth || document.body.scrollWidth;
    // console.log(osTop)
    if (osTop>300 && osWidth>865) {
      tocbox.style.display = "block"
    }
    if (osTop<300 || osWidth<865) {
      tocbox.style.display = "none"
    }
  }
</script>
                <footer>
                    <div class="icons">
                    </div>
                    <span id="busuanzi_container_page_pv" style="padding: 10px">本文阅读量<span id="busuanzi_value_page_pv"></span>次</span>
                    <span id="busuanzi_container_site_pv" style="padding: 10px">本站总访问量<span id="busuanzi_value_site_pv"></span>次</span>
                    <span id="busuanzi_container_site_uv" style="padding: 10px">本站总访客数<span id="busuanzi_value_site_uv"></span>人</span>
                    <p>© <script>document.write(moment().format('YYYY'));</script> 749B</p>
                </footer>
        </div>
</body>
</html>